package xxl.robotlegs.extensions.viewmanager.impl 
{
	import xxl.robotlegs.extensions.viewmanager.api.IViewHandler;
	import flash.display.DisplayObjectContainer;
	import xxl.robotlegs.extensions.viewmanager.api.IViewManager;
	import xxl.signals.api.IMapSignal;
	/**
	 * ...
	 * @author XXL
	 */
	public class ViewManager implements IViewManager
	{
		private const _signal:IMapSignal = new ViewManagerSignal();
		private const _containers:Vector.<DisplayObjectContainer> = new Vector.<DisplayObjectContainer>;
		private const _handlers:Vector.<IViewHandler> = new Vector.<IViewHandler>;
		private var _registry:ContainerRegistry;
		
		public function ViewManager(containerRegistry:ContainerRegistry) 
		{
			_registry = containerRegistry;
		}
		
		private function validContainer(container:DisplayObjectContainer):Boolean
		{
			const len:int = _containers.length;
			for (var i:int = 0; i < len; i++) 
			{
				var registeredContainer:DisplayObjectContainer = _containers[i];
				if (container == registeredContainer)
				{
					return false;
				}
				if (registeredContainer.contains(container) || container.contains(registeredContainer))
				{
					throw new Error("Container不能互相包含");
				}
			}
			return true;
		}
		
		/* INTERFACE xxl.robotlegs.extensions.viewmanager.api.IViewManager */
		
		public function get containers():Vector.<DisplayObjectContainer> 
		{
			return _containers;
		}
		
		public function addContainer(container:DisplayObjectContainer):void 
		{
			if (!validContainer(container))
			{
				return;
			}
			_containers.push(container);
			
			const len:int = _handlers.length;
			for (var i:int = 0; i < len; i++) 
			{
				_registry.addContainer(container).addHandler(_handlers[i]);
			}
			signal.dispatch(ViewManagerSignal.CONTAINER_ADD, container, null);
		}
		
		public function removeContainer(container:DisplayObjectContainer):void 
		{
			const index:int = _containers.indexOf(container);
			if (index < 0)
			{
				return;
			}
			_containers.splice(index, 1);
			
			const binding:ContainerBinding = _registry.getBinding(container);
			const len:int = _handlers.length;
			for (var i:int = 0; i < len; i++) 
			{
				binding.removeHandler(_handlers[i]);
			}
			signal.dispatch(ViewManagerSignal.CONTAINER_REMOVE, container, null);
		}
		
		public function addViewHandler(handler:IViewHandler):void 
		{
			if (_handlers.indexOf(handler) >= 0)
			{
				return;
			}
			_handlers.push(handler);
			const len:int = _containers.length;
			for (var i:int = 0; i < len; i++) 
			{
				_registry.addContainer(_containers[i]).addHandler(handler);
			}
			signal.dispatch(ViewManagerSignal.HANDLER_ADD, null, handler);
		}
		
		public function removeViewHandler(handler:IViewHandler):void 
		{
			const index:int = _handlers.indexOf(handler);
			if (index < 0)
			{
				return;
			}
			_handlers.splice(index, 1);
			const len:int = _containers.length;
			for (var i:int = 0; i < len; i++) 
			{
				_registry.getBinding(_containers[i]).removeHandler(handler);
			}
			signal.dispatch(ViewManagerSignal.HANDLER_REMOVE, null, handler);
		}
		
		public function removeAllHandlers():void 
		{
			for (var i:int = _containers.length; i--; )
			{
				const binding:ContainerBinding = _registry.getBinding(_containers[i]);
				for (var j:int = _handlers.length; j--; )
				{
					binding.removeHandler(_handlers[j]);
				}
			}
		}
		
		public function get signal():IMapSignal
		{
			return _signal;
		}
		
	}

}